package com.zhiche.wms.service.opbaas.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.toolkit.CollectionUtils;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.qiniu.storage.model.FileInfo;
import com.zhiche.wms.core.supports.BaseException;
import com.zhiche.wms.core.supports.constant.OpConstant;
import com.zhiche.wms.core.supports.enums.InterfaceVisitTypeEnum;
import com.zhiche.wms.core.supports.enums.TableStatusEnum;
import com.zhiche.wms.core.utils.SnowFlakeId;
import com.zhiche.wms.core.utils.qiniu.QiNiuUtil;
import com.zhiche.wms.domain.mapper.opbaas.ExceptionConfigurationMapper;
import com.zhiche.wms.domain.mapper.opbaas.ExceptionLoggerMapper;
import com.zhiche.wms.domain.mapper.opbaas.ExceptionRegisterMapper;
import com.zhiche.wms.domain.mapper.opbaas.OpTaskMapper;
import com.zhiche.wms.domain.mapper.otm.OtmOrderReleaseMapper;
import com.zhiche.wms.domain.model.opbaas.ExceptionRegister;
import com.zhiche.wms.domain.model.opbaas.ExceptionRegisterLog;
import com.zhiche.wms.domain.model.opbaas.ExceptionRegisterPicture;
import com.zhiche.wms.domain.model.opbaas.OpTask;
import com.zhiche.wms.domain.model.otm.OtmOrderRelease;
import com.zhiche.wms.domain.model.sys.User;
import com.zhiche.wms.dto.opbaas.paramdto.CommonConditionParamDTO;
import com.zhiche.wms.dto.opbaas.paramdto.ExceHandlingParamDTO;
import com.zhiche.wms.dto.opbaas.paramdto.ExceptionRegisterDetailParamDTO;
import com.zhiche.wms.dto.opbaas.paramdto.ExceptionRegisterParamDTO;
import com.zhiche.wms.dto.opbaas.resultdto.ExResultDTO;
import com.zhiche.wms.dto.opbaas.resultdto.ExceptionRegisterDetailDTO;
import com.zhiche.wms.dto.opbaas.resultdto.TaskDetailResultDTO;
import com.zhiche.wms.dto.opbaas.resultdto.TaskReleaseResultDTO;
import com.zhiche.wms.service.opbaas.ExceptionToOTMService;
import com.zhiche.wms.service.opbaas.IExceptionConfigurationService;
import com.zhiche.wms.service.opbaas.IExceptionRegisterService;
import com.zhiche.wms.service.otm.IOtmOrderReleaseService;
import com.zhiche.wms.service.sys.IUserService;
import com.zhiche.wms.service.utils.CommonMethod;
import com.zhiche.wms.service.utils.OTMCodeMap;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * <p>
 * 异常登记 服务实现类
 * </p>
 *
 * @author user
 * @since 2018-05-24
 */
@Service
public class ExceptionRegisterServiceImpl extends ServiceImpl<ExceptionRegisterMapper, ExceptionRegister> implements IExceptionRegisterService {
    private static final Logger LOGGER = LoggerFactory.getLogger(ExceptionRegisterServiceImpl.class);


    public final static List<String> EXCEPTION_STATUS_List = new ArrayList<>();

    static {
        EXCEPTION_STATUS_List.add(TableStatusEnum.STATUS_10.getCode());
        EXCEPTION_STATUS_List.add(TableStatusEnum.STATUS_40.getCode());
        EXCEPTION_STATUS_List.add(TableStatusEnum.STATUS_50.getCode());
        EXCEPTION_STATUS_List.add(TableStatusEnum.STATUS_60.getCode());
    }

    @Autowired
    private OpTaskMapper opTaskMapper;
    @Autowired
    private ExceptionRegisterPictureServiceImpl registerPictureService;
    @Autowired
    private IUserService userService;
    @Autowired
    private IOtmOrderReleaseService releaseService;
    @Autowired
    private SnowFlakeId flakeId;
    @Autowired
    ExceptionToOTMService exceptionToOTMService;
    @Autowired
    ExceptionConfigurationMapper exceptionConfigurationMapper;
    @Autowired
    IExceptionConfigurationService iExceptionConfigurationService;
    @Autowired
    OtmOrderReleaseMapper otmOrderReleaseMapper;
    @Autowired
    ExceptionRegisterMapper exceptionRegisterMapper;
    @Autowired
    ExceptionLoggerMapper exceptionLoggerMapper;

    /**
     * 点击/扫描获取异常信息
     */
    @Override
    public List<ExResultDTO> getExCount(ExceptionRegisterParamDTO dto) {
        if (dto == null) {
            throw new BaseException("参数不能为空!");
        }
        String visitType = dto.getVisitType();
        if (StringUtils.isBlank(visitType)) {
            throw new BaseException("访问方式不能为空!");
        }
        List<ExResultDTO> resultDTO = null;


        if (InterfaceVisitTypeEnum.CLICK_TYPE.getCode().equals(visitType)) {
            resultDTO = getExceptionCountByTaskId(dto);
        }
        if (InterfaceVisitTypeEnum.SCAN_TYPE.getCode().equals(visitType)) {
            resultDTO = updateExceptionInfoForScan(dto);
        }
        return resultDTO;
    }

    /**
     * <p>
     * 获取菜单下异常图片信息
     * </p>
     */
    @Override
    public List<ExResultDTO> getExceptionPicUrl(ExceptionRegisterParamDTO dto) {
        if (dto == null) {
            throw new BaseException("参数不能为空!");
        }
        String level1Code = dto.getLevel1Code();
        String orderNo = dto.getOrderNo();
        String vin = dto.getVin();
        String taskType = dto.getTaskType();
        if (StringUtils.isBlank(taskType)) {
            throw new BaseException("任务类型不能为空!");
        }
        if (StringUtils.isBlank(level1Code)) {
            throw new BaseException("一级区域code不能为空!");
        }
        if (StringUtils.isBlank(orderNo)) {
            throw new BaseException("订单号不能为空!");
        }
        if (StringUtils.isBlank(vin)) {
            throw new BaseException("车架号不能为空!");
        }

        HashMap<String, Object> params = Maps.newHashMap();
        params.put("vin", vin);
        params.put("orderNo", orderNo);
        params.put("level1Code", level1Code);
        params.put("taskType", taskType);
        params.put("status10", TableStatusEnum.STATUS_10.getCode());
        params.put("dealing", TableStatusEnum.STATUS_20.getCode());
        params.put("orderBy", "a.ex_level3 asc");
        List<ExResultDTO> resultDTOS = baseMapper.queryExDetail(params);
        if (CollectionUtils.isNotEmpty(resultDTOS)) {
            //返回图片的url
            resultDTOS.forEach(v -> {
                List<ExceptionRegisterDetailDTO> detailDTOS = v.getExceptionDetails();
                detailDTOS.forEach(e -> e.setPicUrl(QiNiuUtil.generateDownloadURL(e.getPicKey(), "")));
            });
        }
        return resultDTOS;
    }

    /**
     * <p>
     * 获取异常明细（包括图片信息）
     * </p>
     */
    @Override
    public Page<ExResultDTO> queryExceptionList(Page<ExResultDTO> page) {
        Map<String, Object> condition = page.getCondition();
        Wrapper<ExResultDTO> ew = new EntityWrapper<>();
        if (condition != null) {
            buildCondtion(condition, ew);
        }

        ew.groupBy("a.vin");
        baseMapper.updateSQLMode();
        List<ExResultDTO> resultDTOS = baseMapper.selectExDetailPage(page, ew);
        if (CollectionUtils.isNotEmpty(resultDTOS)) {
            //返回异常描述和图片的url
            resultDTOS.forEach(v -> {
                if (StringUtils.isNotBlank(v.getExDescribe()) && StringUtils.isNotBlank(v.getPicKey())) {
                    String[] exDescribes = v.getExDescribe().split(",");
                    String[] picKeys = v.getPicKey().split(",");
                    List<Map<String, String>> picUrlInfoList = new ArrayList<>();
                    for (int i = 0; i < picKeys.length; i++) {
                        Map<String, String> map = new HashMap<>();
                        map.put("exDescribe", exDescribes[i]);
                        if(StringUtils.isNotBlank(v.getRemarks())){
                            String [] remarks = v.getRemarks().split(",");
                            if(picKeys.length == remarks.length){
                                map.put("remark",remarks[i]);
                            }else {
                                map.put("remark",remarks[0]);
                            }
                        }
                        map.put("picUrl", QiNiuUtil.generateDownloadURL(picKeys[i], ""));
                        picUrlInfoList.add(map);
                    }
                    v.setPicUrlInfoList(picUrlInfoList);
                }
            });
        }
        page.setRecords(resultDTOS);
        return page;
    }

    @Override
    public List<ExResultDTO> queryExportExcpList(Page<ExResultDTO> page) {
        Map<String, Object> condition = page.getCondition();
        Wrapper<ExResultDTO> ew = new EntityWrapper<>();
        if (condition != null) {
            buildCondtion(condition, ew);
        }
        ew.groupBy("a.vin");
        baseMapper.updateSQLMode();
        List<ExResultDTO> resultDTOS = baseMapper.queryExportExcpList(ew);
        if (CollectionUtils.isEmpty(resultDTOS)) {
            throw new BaseException("未查询到对应异常信息");
        }
        return resultDTOS;
    }

    private void buildCondtion(Map<String, Object> condition, Wrapper<ExResultDTO> ew) {
        if (condition.containsKey("taskNode") && Objects.nonNull(condition.get("taskNode"))) {
            ew.eq("a.task_node", condition.get("taskNode"));
        }
        if (condition.containsKey("orderNo") && Objects.nonNull(condition.get("orderNo"))) {
            ew.like("a.oms_order_no", condition.get("orderNo").toString());
        }
        if (condition.containsKey("status") && Objects.nonNull(condition.get("status"))) {
            ew.eq("a.status", condition.get("status"));
        }
        if (condition.containsKey("dealStatus") && Objects.nonNull(condition.get("dealStatus"))) {
            ew.eq("a.deal_status", condition.get("dealStatus"));
        }
        if (condition.containsKey("startDate") && Objects.nonNull(condition.get("startDate"))) {
            ew.ge("a.register_time", condition.get("startDate").toString());
        }
        if (condition.containsKey("endDate") && Objects.nonNull(condition.get("endDate"))) {
            ew.le("a.register_time", condition.get("endDate").toString());
        }
        if(StringUtils.isEmpty((String)condition.get("startDate")) &&StringUtils.isEmpty((String)condition.get("endDate"))){
            ew.eq("DATE_FORMAT(a.register_time, '%m-%d-%Y')","DATE_FORMAT(NOW(), '%m-%d-%Y'");
        }

        ew.notIn("a.status", TableStatusEnum.STATUS_0.getCode());
        if (condition.containsKey("vin") && StringUtils.isNotEmpty((String)condition.get("vin"))) {
            String vin = condition.get("vin").toString();
            List<String> vins = Arrays.asList(CommonMethod.setVins(vin));
            ew.andNew().in("a.vin", vins).or().like("a.vin", vin);
        }
    }


    /**
     * <p>
     * 获取车辆已经标记的异常信息--通过选择任务列表确定
     * </p>
     */
    @Override
    public ArrayList<ExResultDTO> getExceptionCountByTaskId(ExceptionRegisterParamDTO dto) {

        if (dto == null) {
            throw new BaseException("参数不能为空!");
        }
        User loginUser = userService.getLoginUser();
        if (loginUser == null) {
            throw new BaseException("未查询到登录用户");
        }
        if (StringUtils.isBlank(loginUser.getCode())) {
            throw new BaseException("用户编码不能为空!");
        }
        dto.setUserCode(loginUser.getCode());
        String taskId = dto.getQueryParam();
        String userCode = dto.getUserCode();
        if (StringUtils.isBlank(taskId)) {
            throw new BaseException("任务id不能为空!");
        }
        HashMap<String, Object> queryParam = Maps.newHashMap();
        queryParam.put("taskId", taskId);
        queryParam.put("status50", TableStatusEnum.STATUS_50.getCode());
        queryParam.put("start", 0);
        queryParam.put("end", 1);
        List<TaskDetailResultDTO> result = opTaskMapper.getTaskDetail(queryParam);
        if (CollectionUtils.isEmpty(result)) {
            throw new BaseException("未查询到任务id" + taskId + "的任务信息");
        }
        TaskDetailResultDTO detailResultDTO = result.get(0);
        String taskType = detailResultDTO.getTaskType();
        //查寻车辆的异常信息
        HashMap<Object, Object> params = Maps.newHashMap();
        params.put("status10", TableStatusEnum.STATUS_10.getCode());
        params.put("dealing", TableStatusEnum.STATUS_20.getCode());
        params.put("parentCode", TableStatusEnum.STATUS_0.getCode());
        params.put("vin", detailResultDTO.getVin());
        params.put("taskType", taskType);
        params.put("orderNo", detailResultDTO.getOrderNo());
        params.put("orderBy", "a.CODE");
        baseMapper.updateSQLMode();
        List<ExceptionRegisterDetailDTO> countResult = baseMapper.countExDetail(params);
        ArrayList<ExResultDTO> resultList = Lists.newArrayList();
        ExResultDTO resultDTO = new ExResultDTO();
        resultDTO.setTaskId(taskId);
        resultDTO.setTaskType(taskType);
        resultDTO.setUserCode(userCode);
        resultDTO.setExceptionDetails(countResult);
        resultDTO.setVin(detailResultDTO.getVin());
        resultDTO.setOrderNo(detailResultDTO.getOrderNo());
        resultDTO.setVehicle(detailResultDTO.getVehicle());
        resultDTO.setQrCode(detailResultDTO.getQrCode());
        Wrapper<ExceptionRegister> exceptionRegisterWrapper=new EntityWrapper<>();
        exceptionRegisterWrapper.eq("vin",detailResultDTO.getVin());
        List<ExceptionRegister> exceptionRegisters = this.selectList(exceptionRegisterWrapper);
        if (CollectionUtils.isNotEmpty(exceptionRegisters)) {
            resultDTO.setOtmStatus(exceptionRegisters.get(0).getOtmStatus());
        }

        resultList.add(resultDTO);
        return resultList;
    }

    /**
     * <p>
     * 通过扫描获取异常信息
     * </p>
     *
     * @param dto 参数封装
     */
    @Override
    public ArrayList<ExResultDTO> updateExceptionInfoForScan(ExceptionRegisterParamDTO dto) {
        if (dto == null) {
            throw new BaseException("参数不能为空!");
        }
        User loginUser = userService.getLoginUser();
        if (loginUser == null) {
            throw new BaseException("未查询到登录用户");
        }
        if (StringUtils.isBlank(loginUser.getCode())) {
            throw new BaseException("用户编码不能为空!");
        }
        dto.setUserCode(loginUser.getCode());
        String userCode = dto.getUserCode();
        String queryParam = dto.getQueryParam();
        if (StringUtils.isBlank(queryParam)) {
            throw new BaseException("查询订单号或车架号不能为空!");
        }
        HashMap<String, Object> params = Maps.newHashMap();
        params.put("queryParam", queryParam);
        params.put("likeVin", "%" + queryParam + "%");
        params.put("userCode", userCode);
        params.put("userId", loginUser.getId());
        params.put("status50", TableStatusEnum.STATUS_50.getCode());
        params.put("orderBy", "a.gmt_create desc,a.id desc");
        params.put("start", 0);
        params.put("end", 1);
        //首页查询用户对应起运地下的所有运单
        List<TaskReleaseResultDTO> dtoList = releaseService.queryRealeaseInfo(params);
        if (CollectionUtils.isEmpty(dtoList)) {
            throw new BaseException("未查询到对应的运单信息!");
        }
        TaskReleaseResultDTO releaseDTO = dtoList.get(0);
        //查询任务详情,及异常信息
        HashMap<String, Object> map = Maps.newHashMap();
        map.put("releaseGid", releaseDTO.getOrderReleaseGid());
        map.put("status50", TableStatusEnum.STATUS_50.getCode());
        map.put("vin", releaseDTO.getAttribute7());
        map.put("orderBy", "b.type,b.status");
        map.put("start", 0);
        map.put("end", 10);
        List<TaskDetailResultDTO> result = opTaskMapper.getTaskDetailScan(map);
        if (CollectionUtils.isNotEmpty(result)) {
            TaskDetailResultDTO taskDetailResultDTO = result.get(0);
            HashMap<Object, Object> exceptionParam = Maps.newHashMap();
            exceptionParam.put("status10", TableStatusEnum.STATUS_10.getCode());
            exceptionParam.put("dealing", TableStatusEnum.STATUS_20.getCode());
            exceptionParam.put("parentCode", TableStatusEnum.STATUS_0.getCode());
            exceptionParam.put("vin", taskDetailResultDTO.getVin());
            exceptionParam.put("orderNo", taskDetailResultDTO.getOrderNo());
            exceptionParam.put("taskType", taskDetailResultDTO.getTaskType());
            exceptionParam.put("orderBy", "a.sort");
            baseMapper.updateSQLMode();
            List<ExceptionRegisterDetailDTO> countResult = baseMapper.countExDetail(exceptionParam);
            ArrayList<ExResultDTO> resultList = Lists.newArrayList();
            ExResultDTO resultDTO = new ExResultDTO();
            resultDTO.setTaskId(taskDetailResultDTO.getTaskId());
            resultDTO.setTaskType(taskDetailResultDTO.getTaskType());
            resultDTO.setUserCode(userCode);
            resultDTO.setExceptionDetails(countResult);
            resultDTO.setVin(taskDetailResultDTO.getVin());
            resultDTO.setOrderNo(taskDetailResultDTO.getOrderNo());
            resultDTO.setVehicle(taskDetailResultDTO.getVehicle());
            resultDTO.setQrCode(taskDetailResultDTO.getQrCode());
            resultList.add(resultDTO);
            return resultList;
        }
        return null;
    }


    /**
     * <p>
     * 登记异常
     * </p>
     */
    @Override
    public void updateNoteException(ExceptionRegisterParamDTO dto) {
        if (dto == null) {
            throw new BaseException("参数不能为空!");
        }
        User loginUser = userService.getLoginUser();
        if (loginUser == null) {
            throw new BaseException("未查询到登录用户");
        }
        if (StringUtils.isBlank(loginUser.getCode())) {
            throw new BaseException("用户编码不能为空!");
        }

        dto.setUserCode(loginUser.getCode());
        String vin = dto.getVin();
        String taskType = dto.getTaskType();
        String userCode = dto.getUserCode();
        String orderNo = dto.getOrderNo();
        String level1Name = dto.getLevel1Name();
        String level1Code = dto.getLevel1Code();
        String taskId = dto.getTaskId();
        String orderReleaseGid = dto.getOrderReleaseGid();
        if (StringUtils.isBlank(orderNo)) {
            throw new BaseException("订单号不能为空!");
        }
        if (StringUtils.isBlank(vin)) {
            throw new BaseException("车架号不能为空!");
        }
        if (StringUtils.isBlank(taskType)) {
            throw new BaseException("任务类型不能为空!");
        }
        if (StringUtils.isBlank(level1Code)) {
            throw new BaseException("异常区域code1不能为空!");
        }
        if (StringUtils.isBlank(level1Name)) {
            throw new BaseException("异常区域name1不能为空!");
        }
        if (StringUtils.isBlank(taskId)) {
            throw new BaseException("单据号ID不能为空");
        }
      /*  if (StringUtils.isBlank(orderReleaseGid)) {
            throw new BaseException("系统运单号OR不能为空");
        }*/
        String exceptionDetails = dto.getExceptionDetails();
        List<ExceptionRegisterDetailParamDTO> detailParamDTOS = JSONObject.parseArray(exceptionDetails, ExceptionRegisterDetailParamDTO.class);
        //删除一级区域下所有异常信息
        HashMap<Object, Object> params = Maps.newHashMap();
        params.put("level1Code", level1Code);
        params.put("orderNo", orderNo);
        params.put("vin", vin);
        params.put("taskType", taskType);
        params.put("status10", TableStatusEnum.STATUS_10.getCode());
        params.put("status20", TableStatusEnum.STATUS_20.getCode());
        params.put("status0", TableStatusEnum.STATUS_0.getCode());
        baseMapper.deleteExRegister(params);
        ArrayList<ExceptionRegister> insertExceptions = Lists.newArrayList();
        ArrayList<ExceptionRegisterPicture> insertPics = Lists.newArrayList();
        if (CollectionUtils.isNotEmpty(detailParamDTOS)) {
            //插入新的异常信息
            detailParamDTOS.forEach(v -> {
                if (StringUtils.isBlank(v.getLevel2Code())) {
                    throw new BaseException("二级code参数不能为空");
                }
                if (StringUtils.isBlank(v.getLevel2Name())) {
                    throw new BaseException("二级name参数不能为空");
                }
                if (StringUtils.isBlank(v.getLevel3Code())) {
                    throw new BaseException("三级code参数不能为空");
                }
                if (StringUtils.isBlank(v.getLevel3Name())) {
                    throw new BaseException("三级code参数不能为空");
                }
                if (StringUtils.isBlank(v.getPicKeys())) {
                    throw new BaseException("质损异常图片不能为空");
                }
                ExceptionRegister register = new ExceptionRegister();
                register.setId(String.valueOf(flakeId.nextId()));
                register.setOmsOrderNo(orderNo);
                register.setTaskNode(taskType);
                register.setVin(vin);
                register.setHouseId(dto.getHouseId());
                register.setReleaseGid(orderReleaseGid);
                register.setQrCode(dto.getQrCode());
                register.setBusinessDoc(taskId);
                register.setExLevel1(level1Code);
                register.setExLevel2(v.getLevel2Code());
                register.setExLevel3(v.getLevel3Code());
                if (StringUtils.isNotBlank(dto.getLevel1Name())
                        && StringUtils.isNotBlank(v.getLevel2Name())
                        && StringUtils.isNotBlank(v.getLevel3Name())) {
                    register.setExDescribe(dto.getLevel1Name() + "_" + v.getLevel2Name() + "_" + v.getLevel3Name());
                }
                register.setRegisterUser(userCode);
                register.setRegisterTime(new Date());
                register.setDealStatus(TableStatusEnum.STATUS_10.getCode());
                register.setStatus(TableStatusEnum.STATUS_10.getCode());
                register.setGmtCreate(new Date());
                register.setGmtModified(new Date());
                register.setUserCreate(userCode);
                register.setUserModified(userCode);
                if(StringUtils.isNotBlank(v.getRemark())){
                    register.setRemark(v.getRemark());
                }
                if (StringUtils.isNotBlank(v.getPicKeys())) {
                    String[] keys = v.getPicKeys().split(",");
                    for (String key : keys) {
                        ExceptionRegisterPicture picture = new ExceptionRegisterPicture();
                        picture.setId(String.valueOf(flakeId.nextId()));
                        picture.setExceptionId(register.getId());
                        picture.setGmtCreate(new Date());
                        picture.setGmtModified(new Date());
                        picture.setPicKey(key);
                        FileInfo fileInfo = QiNiuUtil.getFileInfo(key);
                        if (Objects.isNull(fileInfo)) {
                            throw new BaseException("key:" + key + "文件不存在!");
                        }
                        picture.setSize(BigDecimal.valueOf(fileInfo.fsize));
                        picture.setStatus(TableStatusEnum.STATUS_10.getCode());
                        picture.setStorageServer(OpConstant.STORAGE_SERVER);
                        insertPics.add(picture);
                    }
                }
                insertExceptions.add(register);
            });
            if (CollectionUtils.isNotEmpty(insertExceptions) && CollectionUtils.isNotEmpty(insertPics)) {
                insertBatch(insertExceptions);
                registerPictureService.insertBatch(insertPics);
            }
        }
    }


    /**
     * <p>
     * 获取opTask
     * </p>
     */
    private OpTask getOpTask(String userCode,
                             TaskReleaseResultDTO resultDTO,
                             SnowFlakeId flakeId,
                             String statusCode) {
        OpTask task = new OpTask();
        task.setId(String.valueOf(flakeId.nextId()));
        task.setDispatchNo(resultDTO.getAttribute16()); //指令号取release运输指令号
        task.setWaybillNo(resultDTO.getOrderReleaseGid());//运单号取release系统单号
        task.setType(statusCode);
        task.setStatus(TableStatusEnum.STATUS_10.getCode());
        task.setUserCreate(userCode);
        task.setGmtCreate(new Date());
        task.setGmtModified(new Date());
        return task;
    }

    @Override
    public Page<ExResultDTO> queryExceptionDetail(Page<ExResultDTO> page) {
        Map<String, Object> condition = page.getCondition();
        Wrapper<ExResultDTO> ew = new EntityWrapper<>();
        if (condition.containsKey("vin") && Objects.isNull(condition.get("vin"))) {
            throw new BaseException("车架号不能为空");
        }
        ew.ne("a.status", TableStatusEnum.STATUS_0.getCode());
        ew.eq("a.vin",condition.get("vin"));
        baseMapper.updateSQLMode();
        List<ExResultDTO> resultDTOS = baseMapper.selectExListDetail(page, ew);
        if (CollectionUtils.isNotEmpty(resultDTOS)) {
            for (ExResultDTO resultDTO : resultDTOS) {
                resultDTO.setPicUrl(QiNiuUtil.generateDownloadURL(resultDTO.getPicKey(), ""));
            }
        }
        page.setRecords(resultDTOS);
        return page;
    }

    @Override
    public void exceptionHandling (ExceHandlingParamDTO exceHandlingParamDTO) {
        Long[] ids = exceHandlingParamDTO.getIds();
        if (ids == null) {
            throw new BaseException("id不能为空");
        }
        //dealType处理方式: (10:返厂维修,20:出库维修,30:库内维修,40:带伤发运;50 异常关闭;60 驳回发运)
        if (StringUtils.isBlank(exceHandlingParamDTO.getDealType())) {
            throw new BaseException("请选择处理方式");
        }

        Wrapper<ExceptionRegister> ew = new EntityWrapper<>();
        ew.in("id", ids);
        ew.eq("vin", exceHandlingParamDTO.getVin());
        //deal_status为50代表已处理，已处理的异常无需再次处理
        ew.ne("deal_status",TableStatusEnum.STATUS_50.getCode());
        List<ExceptionRegister> exceptionRegisters = baseMapper.selectList(ew);

        //1、设置更新异常发运表的状态
        this.modifiedExceptionStatus(ids, exceHandlingParamDTO);

        Map<String, String> params = new HashMap<>();
        params.put("houseId", exceHandlingParamDTO.getHouseId());
        params.put("lotNo1", exceHandlingParamDTO.getVin());
        params.put("is_factory_exception", TableStatusEnum.STATUS_N.getCode()); //异常处理状态
        //2、40:带伤发运;50 异常关闭 推送OTM
        for (ExceptionRegister exceptionRegister : exceptionRegisters) {
            ExceptionRegister register = baseMapper.selectById(exceptionRegister.getId());
            if (StringUtils.isEmpty(register.getDealType())) {
                throw new BaseException("处理方式为空");
            }
            if (StringUtils.isEmpty(register.getOmsOrderNo())) {
                throw new BaseException("订单号为空");
            }
            //deal_type 处理方式
            if (EXCEPTION_STATUS_List.contains(register.getDealType())) {

                //40:带伤发运;50 异常关闭
                if (register.getDealType().equals(TableStatusEnum.STATUS_50.getCode()) || register.getDealType().equals(TableStatusEnum.STATUS_40.getCode())) {
                    params.put("isCanSend", TableStatusEnum.STATUS_Y.getCode());
                } else if (register.getDealType().equals(TableStatusEnum.STATUS_60.getCode())) {
                    params.put("isCanSend", TableStatusEnum.STATUS_N.getCode());
                    //60 驳回发运
                    Wrapper<ExceptionRegister> exceptionRegisterWrapper = new EntityWrapper<>();
                    exceptionRegisterWrapper.eq("vin", exceHandlingParamDTO.getVin());
                    Integer vinInteger = baseMapper.selectCount(exceptionRegisterWrapper);
                    exceptionRegisterWrapper.eq("deal_type", TableStatusEnum.STATUS_60.getCode());
                    Integer rejectCount = baseMapper.selectCount(exceptionRegisterWrapper);
                    if (vinInteger != rejectCount) {
                        continue;
                    }
                } else if (register.getDealType().equals(TableStatusEnum.STATUS_10.getCode())) {
                    //10 返厂维修
                    params.put("isCanSend", TableStatusEnum.STATUS_N.getCode());
                    params.put("is_factory_exception", TableStatusEnum.STATUS_Y.getCode()); //异常处理状态
                }

                //查询异常照片和异常描述
                Wrapper<ExResultDTO> pictureEw = new EntityWrapper<>();
                if (StringUtils.isNotEmpty(exceHandlingParamDTO.getPictureId())) {
                    String[] picids = exceHandlingParamDTO.getPictureId().split(",");
                    pictureEw.in("b.id", Arrays.asList(picids));
                }
                pictureEw.eq("a.vin", register.getVin());
                pictureEw.ne("a.status", TableStatusEnum.STATUS_0.getCode());
                pictureEw.eq("b.exception_id", register.getId());
                List<ExResultDTO> pictureResult = baseMapper.selectExListDetail(new Page<>(), pictureEw);
                if (CollectionUtils.isNotEmpty(pictureResult)) {
                    for (ExResultDTO exResultDTO : pictureResult) {
                        pushExceptionOtm(register, exResultDTO, params);
                    }
                } else {
                    pushExceptionOtm(register, new ExResultDTO(), params);
                }
            }
        }
    }

    @Override
    public void deleteException (Map<String, String> param) {
        if (null == param || param.isEmpty()) {
            throw new BaseException("删除异常凭据【ids】不能为空");
        }

        if(StringUtils.isBlank(param.get("ids"))){
            throw new BaseException("删除异常凭据【ids】不能为空");
        }

        if(StringUtils.isBlank(param.get("remark"))){
            throw new BaseException("删除异常备注信息【remark】不能为空");
        }

        String[] ids = param.get("ids").split(",");
        ExceptionRegister exceptionRegister = new ExceptionRegister();
        exceptionRegister.setStatus(TableStatusEnum.STATUS_0.getCode());
        exceptionRegister.setRemark(param.get("remark"));
        EntityWrapper<ExceptionRegister> ew = new EntityWrapper<>();
        ew.in("id", ids);
        baseMapper.update(exceptionRegister, ew);
        //删除的信息推送OTM

        for (String id : ids) {
            ExceptionRegister register = baseMapper.selectById(id);
            Map<String, String> params = new HashMap<>();
            params.put("isCanSend", TableStatusEnum.STATUS_Y.getCode());
            params.put("lotNo1", register.getVin());
            params.put("houseId",register.getHouseId());
            params.put("deleted",TableStatusEnum.STATUS_0.getCode());
            pushExceptionOtm(register, new ExResultDTO(), params);
        }
    }

    @Override
    public List<String> saveException (Map<String, String> param) {
        List<String> resultList = new ArrayList<>();
        User loginUser = userService.getLoginUser();
        if (loginUser == null) {
            throw new BaseException("未查询到登录用户");
        }
        if (null == param || param.isEmpty()) {
            throw new BaseException("新增入参【orderRleaseGid】不能为空!");
        }

        if(StringUtils.isBlank(param.get("isCanSend"))){
            throw new BaseException("是否异常可发运【isCanSend】不能为空!");
        }
        if(StringUtils.isBlank(param.get("houseId"))){
            throw new BaseException("仓库【houseId】不能为空!");
        }
        if(StringUtils.isBlank(param.get("estimatedProcessingTime"))){
            throw new BaseException("预计处理异常完成时间【estimatedProcessingTime】不能为空!");
        }


//        String[] orderReleaseGids = param.get("orderRleaseGid").split(",");
        List<String> orderReleaseGids = Arrays.asList(CommonMethod.setVins(param.get("orderRleaseGid")));

        EntityWrapper<OtmOrderRelease> orderEw = new EntityWrapper<>();
        orderEw.in("release_gid", orderReleaseGids);
        orderEw.ne("status", TableStatusEnum.STATUS_50.getCode());
        List<OtmOrderRelease> otmOrderReleases = otmOrderReleaseMapper.selectList(orderEw);
        if(CollectionUtils.isEmpty(otmOrderReleases)){
            throw new BaseException("查询数据为空或者状态无效，请重新输入有效的OR号！");
        }
        for (OtmOrderRelease orderRelease : otmOrderReleases) {
            StringBuffer sb = new StringBuffer();
            EntityWrapper<ExceptionRegister> queryEw = new EntityWrapper<>();
            queryEw.eq("vin",orderRelease.getVin());
            queryEw.eq("release_gid",orderRelease.getReleaseGid());
            queryEw.eq("deal_status",TableStatusEnum.STATUS_10.getCode());
            List<ExceptionRegister> queryList = exceptionRegisterMapper.selectList(queryEw);
            if(CollectionUtils.isNotEmpty(queryList)){
                sb.append("系统运单号:").append(orderRelease.getReleaseGid()).append(":").append("已经存在未处理的异常信息");
                resultList.add(sb.toString());
                continue;
            }

            //新增异常信息
            ExceptionRegister register = new ExceptionRegister();
            register.setGmtCreate(new Date());
            register.setGmtModified(new Date());
            register.setRegisterTime(new Date());
            register.setVin(orderRelease.getVin());
            register.setUserCreate(loginUser.getName());
            register.setQrCode(orderRelease.getQrCode());
            register.setExDescribe("WMS通过OR号手动输入");
            register.setRegisterUser(loginUser.getCode());
            register.setId(String.valueOf(flakeId.nextId()));
            register.setReleaseGid(orderRelease.getReleaseGid());
            register.setOmsOrderNo(orderRelease.getCusOrderNo());
            register.setEstimatedProcessingTime(CommonMethod.stringToDate2(param.get("estimatedProcessingTime")));
            register.setHouseId(param.get("houseId"));
            register.setStatus(TableStatusEnum.STATUS_10.getCode());
            register.setTaskNode(TableStatusEnum.STATUS_1.getCode());
            register.setDealStatus(TableStatusEnum.STATUS_10.getCode());
            register.setBusinessDoc(String.valueOf(orderRelease.getId()));
            register.setRemark(param.get("exceptionReason"));
            exceptionRegisterMapper.insert(register);

            //异常信息推送OTM
            Map<String, String> params = new HashMap<>();
            params.put("isCanSend", param.get("isCanSend"));
            params.put("lotNo1", register.getVin());
            params.put("houseId",param.get("houseId"));
            pushExceptionOtm(register, new ExResultDTO(), params);
        }
        return resultList;
    }

    @Override
    public void pushExceptionOTM (ExceptionRegister register, ExResultDTO exResultDTO, Map<String, String> params) {
        pushExceptionOtm(register, new ExResultDTO(), params);
    }

    @Override
    public void saveExceptionLog (Map<String, String> condition, String jsonParam, String otmResult) {
        try {
            ExceptionRegisterLog exceptionRegisterLog = new ExceptionRegisterLog();
            exceptionRegisterLog.setId(flakeId.nextId());
            exceptionRegisterLog.setExceptionId(Long.valueOf(condition.get("wms_id")));
            exceptionRegisterLog.setPushData(jsonParam);
            exceptionRegisterLog.setPushTime(new Date());
            exceptionRegisterLog.setEstimatedProcessingTime(CommonMethod.stringToDate2(condition.get("estimatedProcessingTime")));
            exceptionRegisterLog.setRemark(condition.get("deleted") == null ? "N" : condition.get("deleted"));
            exceptionRegisterLog.setGmtCreate(new Date());
            exceptionRegisterLog.setOtmResult(otmResult);
            exceptionLoggerMapper.insert(exceptionRegisterLog);
        } catch (Exception e) {
            LOGGER.error("记录异常推送OTM异常{}", e.getMessage());
        }
    }

    @Override
    public void pushException (Map<String, String> paramsVin) {
        List<CommonConditionParamDTO> list = new ArrayList<>();
        //查询异常照片和异常描述
        Wrapper<ExResultDTO> pictureEw = new EntityWrapper<>();
        pictureEw.in("a.vin", Arrays.asList(CommonMethod.setVins(paramsVin.get("vin"))));
        List<ExResultDTO> pictureResult = exceptionRegisterMapper.selectExListDetail(new Page<>(), pictureEw);
        if (CollectionUtils.isNotEmpty(pictureResult)) {
            for (ExResultDTO exResultDTO : pictureResult) {
                CommonConditionParamDTO commonConditionParamDTO = new CommonConditionParamDTO();
                Map<String, String> params = new HashMap<>();
                if (exResultDTO.getStatus().equals(TableStatusEnum.STATUS_0.getCode()) || exResultDTO.getStatus().equals(TableStatusEnum.STATUS_50.getCode())) {
                    params.put("delete", "Y");
                }
                params.put("lotNo1", exResultDTO.getVin());
                params.put("vin", exResultDTO.getVin());
                params.put("is_factory_exception", TableStatusEnum.STATUS_N.getCode()); //是否工厂异常
                params.put("wms_id", exResultDTO.getId());
                params.put("cus_order_no", exResultDTO.getOmsOrderNo());
                params.put("exception_result", exResultDTO.getDealType() == null ? "" : OTMCodeMap.EXCEPTION_DEAL_TYPE.get(exResultDTO.getDealType()));//异常处理方式
                params.put("exception_desc", exResultDTO.getExDescribe());//异常描述
                params.put("phone_url", "");
                if (null != exResultDTO) {
                    params.put("phone_url", exResultDTO.getPicKey());
                }
                params.put("work_node", exResultDTO.getTaskNode() == null ? "" : OTMCodeMap.EXCEPTION_TASK_NODE.get(exResultDTO.getTaskNode()));//登记节点
                params.put("registrant", exResultDTO.getRegisterUser());//登记人
                params.put("exception_type", iExceptionConfigurationService.queryNameByCode(exResultDTO.getExLevel3()));//异常类型
                params.put("exception_handle_status", OTMCodeMap.EXCEPTION_DEAL_STATUS.get(exResultDTO.getDealStatus())); //异常处理状态
                params.put("isCanSend", exResultDTO.getOtmStatus() == null ? "Y" : exResultDTO.getOtmStatus());
                if (null != exResultDTO.getRegisterTime()) {
                    params.put("register_time", CommonMethod.getStringDate(exResultDTO.getRegisterTime())); //登记时间
                }
                params.put("order_release_xid", exResultDTO.getReleaseGid()); //wms运单号
                if(null != exResultDTO.getEstimatedProcessingTime()){
                    params.put("estimatedProcessingTime", CommonMethod.getStringDate(exResultDTO.getEstimatedProcessingTime())); //异常预计处理时间
                }else{
                    Calendar calendar = Calendar.getInstance();
                    calendar.setTime(exResultDTO.getRegisterTime());
                    calendar.set(Calendar.HOUR, calendar.get(Calendar.HOUR) + 12);// 让日期加1
                    String shipDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(calendar.getTime());
                    params.put("estimatedProcessingTime", shipDate); //异常预计处理时间
                }

                if (StringUtils.isNotBlank(exResultDTO.getRemark())) {
                    params.put("remark", exResultDTO.getRemark());
                }
                params.put("houseId",exResultDTO.getHouseId());
                commonConditionParamDTO.setCondition(params);
                list.add(commonConditionParamDTO);
            }
        }
        if (CollectionUtils.isNotEmpty(list)) {
            for (CommonConditionParamDTO conditionParam : list) {
                exceptionToOTMService.isCanSend(conditionParam);
            }
        }
    }

    private void pushExceptionOtm (ExceptionRegister register, ExResultDTO exResultDTO, Map<String, String> params) {
        CommonConditionParamDTO commonConditionParamDTO = new CommonConditionParamDTO();
        params.put("wms_id", register.getId());
        params.put("cus_order_no", register.getOmsOrderNo());
        params.put("exception_result", register.getDealType() == null ? "" : OTMCodeMap.EXCEPTION_DEAL_TYPE.get(register.getDealType()));//异常处理方式
        params.put("exception_desc", register.getExDescribe());//异常描述
        params.put("phone_url", "");
        if (null != exResultDTO) {
            params.put("phone_url", exResultDTO.getPicKey());
        }
        params.put("work_node", register.getTaskNode() == null ? "" : OTMCodeMap.EXCEPTION_TASK_NODE.get(register.getTaskNode()));//登记节点
        params.put("registrant", register.getRegisterUser());//登记人
        params.put("exception_type", iExceptionConfigurationService.queryNameByCode(exResultDTO.getExLevel3()));//异常类型
        params.put("exception_handle_status", OTMCodeMap.EXCEPTION_DEAL_STATUS.get(register.getDealStatus())); //异常处理状态
        params.put("register_time", CommonMethod.getStringDate(register.getRegisterTime())); //登记时间
        params.put("order_release_xid",register.getReleaseGid()==null?"":register.getReleaseGid());
        params.put("estimatedProcessingTime",CommonMethod.getStringDate(register.getEstimatedProcessingTime()));
        params.put("deleted", register.getStatus().equals("0") ? "Y" : "N");
        commonConditionParamDTO.setCondition(params);
        exceptionToOTMService.isCanSend(commonConditionParamDTO);
    }

    /**
     * 根据id修改异常发运表的状态
     *
     */
    private void modifiedExceptionStatus (Long[] ids, ExceHandlingParamDTO exceHandlingParamDTO) {
        //dealType处理方式: (10:返厂维修,20:出库维修,30:库内维修,40:带伤发运;50 异常关闭;60 驳回发运)
        ExceptionRegister exceptionRegister = new ExceptionRegister();
        User loginUser = userService.getLoginUser();
        if (loginUser == null) {
            throw new BaseException("未查询到登录用户");
        }
        for (Long id : ids) {
            exceptionRegister.setId(String.valueOf(id));
            exceptionRegister.setDealType(exceHandlingParamDTO.getDealType());
            if (exceHandlingParamDTO.getDealType().equals(TableStatusEnum.STATUS_60.getCode())) {
                //驳回发运
                this.setExceptionRegister(exceptionRegister, TableStatusEnum.STATUS_N.getCode(), exceHandlingParamDTO.getHouseId(),
                        loginUser.getName(), TableStatusEnum.STATUS_50.getCode());

            } else if (exceHandlingParamDTO.getDealType().equals(TableStatusEnum.STATUS_50.getCode())) {
                //异常关闭
                this.setExceptionRegister(exceptionRegister, TableStatusEnum.STATUS_Y.getCode(), exceHandlingParamDTO.getHouseId(),
                        loginUser.getName(), TableStatusEnum.STATUS_50.getCode());
                exceptionRegister.setStatus(TableStatusEnum.STATUS_30.getCode());

            } else if (exceHandlingParamDTO.getDealType().equals(TableStatusEnum.STATUS_10.getCode())) {
                //返厂维修
                this.setExceptionRegister(exceptionRegister, TableStatusEnum.STATUS_N.getCode(), exceHandlingParamDTO.getHouseId(),
                        loginUser.getName(), TableStatusEnum.STATUS_50.getCode());

            } else {
                this.setExceptionRegister(exceptionRegister, TableStatusEnum.STATUS_Y.getCode(), exceHandlingParamDTO.getHouseId(),
                        loginUser.getName(), TableStatusEnum.STATUS_50.getCode());
            }
            exceptionRegister.setGmtModified(new Date());
            this.updateById(exceptionRegister);
        }
    }

    /**
     * @param exceptionRegister 异常对象
     * @param otmStatus         标识是否可以发运
     * @param houseId           仓库id
     * @param loginName         登录用户名
     * @param dealStatus        处理状态
     */
    private void setExceptionRegister (ExceptionRegister exceptionRegister, String otmStatus, String houseId, String loginName, String dealStatus) {
        exceptionRegister.setOtmStatus(otmStatus);
        exceptionRegister.setHouseId(houseId);
        exceptionRegister.setUserModified(loginName);
        exceptionRegister.setDealStatus(dealStatus);
        exceptionRegister.setDealEndTime(new Date());
    }
}
